package com.zenglx.multilanguage.injector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.methods.*;
import com.baomidou.mybatisplus.core.mapper.Mapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.zenglx.multilanguage.metadata.ZlxTableInfo;
import com.zenglx.multilanguage.metadata.ZlxTableInfoHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * SQL 注入器
 *
 * @author liangxi.zeng
 * @see ZlxSqlInjector
 */

@Primary
@Component
@Slf4j
public class ZlxSqlInjector extends DefaultSqlInjector {


    @Override
    public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
        Class<?> modelClass = ReflectionKit.getSuperClassGenericType(mapperClass, Mapper.class, 0);
        if (modelClass != null) {
            String className = mapperClass.toString();
            Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
            if (!mapperRegistryCache.contains(className)) {
                List<AbstractMethod> methodList = this.getMethodList(mapperClass);
                if (CollectionUtils.isNotEmpty(methodList)) {
                    ZlxTableInfo tableInfo = ZlxTableInfoHelper.initTableInfo(builderAssistant, modelClass,className);
                    // 循环注入自定义方法
                    methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
                } else {
                    log.debug(mapperClass.toString() + ", No effective injection method was found.");
                }
                mapperRegistryCache.add(className);
            }
        }
    }
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
            return Stream.of(
                new com.zenglx.multilanguage.method.Insert(),
                new Delete(),
                new DeleteByMap(),
                new DeleteById(),
                new DeleteBatchByIds(),
                new Update(),
                new UpdateById(),
                new com.zenglx.multilanguage.method.SelectById(),
                new com.zenglx.multilanguage.method.SelectBatchByIds(),
                new SelectByMap(),
                new com.zenglx.multilanguage.method.SelectOne(),
                new com.zenglx.multilanguage.method.SelectCount(),
                new SelectMaps(),
                new SelectMapsPage(),
                new SelectObjs(),
                new com.zenglx.multilanguage.method.SelectList(),
                    new com.zenglx.multilanguage.method.SelectPage()
        ).collect(toList());
    }

}
